﻿using DoNet.Common.Cache;
using DoNet.Common.Extensions;
using DoNet.Common.Helpers;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Caching.StackExchangeRedis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
using System.Threading.Tasks;
using DoNet.ThirdParty.Redis;

namespace DoNet.Extensions.Setups
{
    /// <summary>
    /// Redis缓存 启动服务
    /// </summary>
    public static class CacheSetup
    {
        /// <summary>
        /// Redis缓存 启动服务
        /// </summary>
        /// <param name="services"></param>
        /// <exception cref="ArgumentNullException"></exception>
        public static void AddRedisCacheSetup(this IServiceCollection services, IConfiguration config)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));


            CacheProvider cacheProvider = new CacheProvider
            {
                IsUseRedis = config.app("CacheProvider:UseRedis").ObjectToBool(),
                ConnectionString = config.app("CacheProvider:Redis_ConnectionString"),
                InstanceName = config.app("CacheProvider:Redis_InstanceName")
            };

            //判断是否使用Redis，如果不使用 Redis就默认使用 MemoryCache
            if (cacheProvider.IsUseRedis)
            {
                //Use Redis
                services.AddRedisSetup(cacheProvider.ConnectionString, cacheProvider.InstanceName);

                services.AddSingleton(typeof(ICacheService), new RedisCacheService(new RedisCacheOptions()
                {
                    Configuration = cacheProvider.ConnectionString,
                    InstanceName = cacheProvider.InstanceName
                }, 0));

                services.AddSingleton(typeof(RedisHelper), new RedisHelper(new RedisCacheOptions
                {
                    Configuration = cacheProvider.ConnectionString,
                    InstanceName = cacheProvider.InstanceName
                }, 0));

                services.Configure<DistributedCacheEntryOptions>(option => option.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5));//设置Redis缓存有效时间为5分钟。
            }
            else
            {
                services.AddSingleton<IMemoryCache>(factory =>
                {
                    var cache = new MemoryCache(new MemoryCacheOptions());
                    return cache;
                });
                services.AddSingleton<ICacheService, MemoryCacheService>();
                services.Configure<MemoryCacheEntryOptions>(options => options.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5)); //设置MemoryCache缓存有效时间为5分钟

                services.AddMemoryCache();// 启用MemoryCache
            }

            services.AddSingleton(cacheProvider);//注册缓存配置
        }
    }
}
